/**
 * desc：  这里主要是做脚手架启动的初始化检测以及脚手架的命令注册
 * author：王文军
 * date：  2021/6/29 21:14
 */
"use strict";
const path = require("path");
// START 外部依赖库
const semver = require("semver");
const colors = require("colors/safe");
const userHome = require("user-home");
const pathExists = require("path-exists").sync;
const commander = require("commander");
// END 外部依赖库

// START 本地依赖库
const log = require("@wenjun-cli/log");
const exec = require("@wenjun-cli/exec");
// END 本地依赖库

// START 本地引入文件
const pkg = require("../package.json");
const constant = require("./CONST");
// END 本地引入文件

// 自定义常量
const DEFAULT_CLI_HOME = ".wenjun-cli";
const LOGIN_TOKEN_FILE = ".login_token";

// 初始化环境变量
process.env.WENJUN_CLI_BASE_URL = "http://47.109.18.18:7001";

// 实例化commander
const program = new commander.Command();

async function core() {
  try {
    await prepare();
    registerCommand();
  } catch (e) {
    log.error(e.message);
    if (program.debug) {
      console.log(e);
    }
  }
}

// 命令注册
function registerCommand() {
  program
    .name(Object.keys(pkg.bin)[0])
    .usage(`[command] <options>`)
    .version(pkg.version, "-V, --version", "查看当前脚手架版本", "1.0.0")
    .helpOption("-h, --help", "查看帮助")
    .option("-d, --debug", "是否开启调试模式", false)
    .option("-l, --local", "是否开启本地调试", false)
    .option("-tp, --targetPath <targetPath>", "是否使用本地路径", "");

  //注册自定义init命令
  program
    .command("init [projectName]")
    .option("-f, --force", "是否强制初始化项目")
    .action(exec);

  //注册自定义add命令
  program
    .command("add [templateName]")
    .option("-f, --force", "是否强制添加代码")
    .action(exec);

  //注册自定义publish命令
  program
    .command("publish")
    .option("-rfs, --refreshServer", "强制更新远程Git仓库")
    .option("-rft, --refreshToken", "强制更新远程仓库token")
    .option("-rfo, --refreshOwner", "强制更新远程仓库类型")
    .option("--buildCmd <buildCmd>", "构建命令")
    .option("-pd, --prod", "是否正式发布")
    .option("-ssu, --sshUser <sshUser>", "模板服务器用户名")
    .option("-ssp, --sshIp <sshIp>", "模板服务器IP或域名")
    .option("-sst, --sshPath <sshPath>", "模板服务器上传路径")
    .action(exec);

  //注册自定义登录命令
  program.command("login").description("用户登录").action(exec);

  //注册自定义用户添加命令
  program.command("addUser").description("用户添加").action(exec);

  // 监听debug模式
  program.on("option:debug", () => {
    if (program.debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
  });

  // 监听local模式
  program.on("option:local", () => {
    if (program.local) {
      process.env.WENJUN_CLI_BASE_URL = "http://127.0.0.1:8082";
    }
  });

  // 监听targetPath命令
  program.on("option:targetPath", () => {
    // 在环境变量中指定targetPath
    process.env.CLI_TARGET_PATH = program.targetPath;
  });

  // 监听所有为未注册的命令
  program.on("command:*", (obj) => {
    // 查看所有可用命令
    const allCommands = program.commands.map((cmd) => cmd.name());
    console.log(colors.red("未知命令：" + obj[0]));
    if (allCommands.length > 0) {
      console.log(colors.red("可用命令：" + allCommands.join(",")));
    }
  });

  program.parse(process.argv);

  // 没有输入任何参数时，打印帮助文档
  if (program.args && program.args.length < 1) {
    program.outputHelp();
    console.log(); // 打印一个空行，使得查看更美观
  }
}

// 脚手架启动
async function prepare() {
  checkPkgVersion();
  checkRoot();
  checkUserHome();
  checkEnv();
  await checkGlobalUpdate();
  await checkUserLogin();
}

// 检查当前脚手架是否需要全局更新
async function checkGlobalUpdate() {
  //1.获取当前版本号和模块名
  const currentVersion = pkg.version;
  const npmNode = pkg.name;
  //2.调用npm提供的API,获取当前包所有的版本号
  const { getNpmSemverVersion } = require("@wenjun-cli/get-npm-info");
  const lastVersions = await getNpmSemverVersion(currentVersion, npmNode);
  log.info("heckGlobalUpdate lastVersions", lastVersions);
  if (lastVersions && semver.gt(lastVersions, currentVersion)) {
    log.warn(
      "更新提示",
      colors.yellow(
        `请手动更新${npmNode},当前版本：${currentVersion},最新版本${lastVersions}
        更新命令：npm install -g ${npmNode}
        `
      )
    );
  }
  //3.获取所有版本号，比对那些版本号是大于当前版本号
  //4.获取最新版本号，提示用户更新到该版本
}

// 检查环境变量
function checkEnv() {
  const dotenv = require("dotenv");
  const dotenvPath = path.resolve(userHome, DEFAULT_CLI_HOME, ".env");
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: path.resolve(userHome, ".env"),
    });
  }
  createDefaultConfig();
}

// 初始化环境变量的默认值
function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, constant.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

// 检查脚手架版本
function checkPkgVersion() {
  // debug
  log.info("wenjun-cli", pkg.version);
}

// 检查系统root启动
function checkRoot() {
  // 自动检查是否是root启动并且自动降级权限
  // 暂时请安装root-check的1.0.0版本，最新版的会有些许问题
  const rootCheck = require("root-check");
  rootCheck();
}

// 检查用户主目录
function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red("当前登陆用户主目录不存在！"));
  }
}

// 检查用户是否登录
async function checkUserLogin() {
  const loginTokenPath = path.resolve(
    userHome,
    DEFAULT_CLI_HOME,
    LOGIN_TOKEN_FILE
  );
  if (!pathExists(loginTokenPath)) {
    log.warn(
      "当前状态为未登录！可运行wenjun-cli login 进行登录，以便后续操作！"
    );
  }
}

module.exports = core;
